package service

import (
	"errors"
	"fmt"

	"mutu/misc"
	"mutu/misc/conf"
	"mutu/misc/cstore"
	"mutu/misc/log"
	"mutu/models"
)

type MatterManager struct {
}

var (
	MatterService = MatterManager{}
)

func (p MatterManager) ReadUser(m *models.Matter) error {
	var err error
	m.User, err = UserService.GetUserByUuid(m.UserId)
	return err
}

func (p MatterManager) ReadReSource(m *models.Matter) error {
	var err error
	if m.Flag == conf.F_Matter_PSD {
		m.ShowResource, err = ResourceService.GetResourceByUuid(m.ShowId)
		m.PsdResource, err = ResourceService.GetResourceByUuid(m.PsdId)
	} else {
		m.PicResource, err = ResourceService.GetResourceByUuid(m.PicId)
	}
	return err
}

func (p MatterManager) ReadCategory(m *models.Matter) error {
	var err error
	m.Category, err = CategoryService.GetRelCategory(m.Flag, m.Uuid)
	return err
}

func (p MatterManager) ReadTag(m *models.Matter) error {
	var err error
	m.Tags, err = TagService.GetRelTags(m.Flag, m.Uuid)
	return err
}

func (p MatterManager) CreateMatter(cat int, tags []int, m *models.Matter) error {
	var err error
	var r *models.Resource
	if m.Flag == conf.F_Matter_PIC {
		r, err = ResourceService.GetResourceByUuid(m.PicId)
	} else if m.Flag == conf.F_Matter_PSD {
		r, err = ResourceService.GetResourceByUuid(m.ShowId)
	}

	if err != nil {
		log.Log.Error("创建素材-读取资源出错，%s", err)
	}
	m.Link = cstore.GetBaseUrl(r.Public, r.Key)
	m.Size = r.Size
	m.Height = r.Height
	m.Width = r.Width

	if m.Uuid == "" {
		m.Uuid = misc.NewUUID()
	}
	m.Deleted = false

	if _, err := models.Orm.Insert(m); err != nil {
		log.Log.Error("创建素材-保存素材出错，%s", err)
		return err
	}

	//更新资源使用
	if m.Flag == conf.F_Matter_PIC {
		ResourceService.UpdateResourceUsedBy(m.PicId, m.Uuid)
	} else if m.Flag == conf.F_Matter_PSD {
		ResourceService.UpdateResourceUsedBy(m.ShowId, m.Uuid)
		ResourceService.UpdateResourceUsedBy(m.PsdId, m.Uuid)
	}

	if err := CategoryService.CreateRelCategory(cat, m.Flag, m.Uuid); err != nil {
		log.Log.Error("创建素材-保存素材分类出错，%s", err)
		return err
	}

	if err := TagService.CreateRelTags(tags, m.Flag, m.Uuid); err != nil {
		log.Log.Error("创建素材-保存素材标签出错，%s", err)
		return err
	}

	return nil
}

func (p MatterManager) EditMatter(cat int, tags []int, m *models.Matter) error {
	nm := &models.Matter{
		Uuid: m.Uuid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("更新素材-读取原素材<%s>信息出错，%s", nm.Uuid, err)
		return err
	}
	if nm.UserId != m.UserId {
		log.Log.Error("更新素材<%s>失败，没有权限", nm.Uuid)
		return errors.New("没有权限")
	}

	//解除之前的关联
	if err := CategoryService.ReleaseRelCategory(nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("更新素材<%s>-解除分类关系出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.ReleaseRelTags(nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("更新素材<%s>-解除标签关系出错，%s", nm.Uuid, err)
		return err
	}

	//创建新的关联
	if err := CategoryService.CreateRelCategory(cat, nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("更新素材<%s>-保存素材分类出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.CreateRelTags(tags, nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("更新素材<%s>-保存素材标签出错，%s", nm.Uuid, err)
		return err
	}

	var args []string
	if nm.Title != m.Title {
		nm.Title = m.Title
		args = append(args, "Title")
	}
	if nm.Desc != m.Desc {
		nm.Desc = m.Desc
		args = append(args, "Desc")
	}

	if nm.Flag == conf.F_Matter_PSD && nm.Score != m.Score {
		nm.Score = m.Score
		args = append(args, "Score")
	}

	if len(args) > 0 {
		args = append(args, "UpdateAt")
		if _, err := models.Orm.Update(nm, args...); err != nil {
			log.Log.Error("更新素材<%s>-保存素材出错，%s", nm.Uuid, err)
			return err
		}
	}

	return nil
}

func (p MatterManager) DeleteMatter(userId, uuid string) error {
	nm := &models.Matter{
		Uuid: uuid,
	}
	if err := models.Orm.Read(nm, "Uuid"); err != nil {
		log.Log.Error("删除素材-读取原素材<%s>信息出错，%s", nm.Uuid, err)
		return err
	}
	if nm.UserId != userId {
		log.Log.Error("删除素材<%s>失败，没有权限", nm.Uuid)
		return errors.New("没有权限")
	}

	//解除之前的关联
	if err := CategoryService.ReleaseRelCategory(nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("删除素材<%s>-解除分类关系出错，%s", nm.Uuid, err)
		return err
	}

	if err := TagService.ReleaseRelTags(nm.Flag, nm.Uuid); err != nil {
		log.Log.Error("删除素材<%s>-解除标签关系出错，%s", nm.Uuid, err)
		return err
	}

	nm.Deleted = true
	nm.DeleteAt = misc.GTimer.Now
	if _, err := models.Orm.Update(nm, "Deleted", "DeleteAt"); err != nil {
		log.Log.Error("删除素材<%s>-更新素材删除状态出错，%s", nm.Uuid, err)
		return err
	}

	return nil
}

func (p MatterManager) GetUserMattersByFlag(flag int, userId string) ([]*models.Matter, error) {
	var arr []*models.Matter
	_, err := models.Orm.QueryTable("Matter").Filter("Flag", flag).Filter("UserId", userId).Filter("Deleted", false).All(&arr)
	if err != nil {
		log.Log.Error("读取用户<%s>, 类型<%d>素材出错，%s", userId, flag, err)
		return nil, err
	}

	return arr, nil
}

func (p MatterManager) GetMatterByUuid(uuid string) (*models.Matter, error) {
	m := &models.Matter{
		Uuid: uuid,
	}
	err := models.Orm.Read(m, "Uuid")
	if err != nil {
		log.Log.Error("读取素材<%s>出错，%s", uuid, err)
		return nil, err
	}

	return m, nil
}

func (p MatterManager) FillMatterInfo(m *models.Matter, fills ...bool) error {
	if m.Flag == conf.F_Matter_PSD {
		m.IsPsd = true
	} else {
		m.IsPsd = false
	}

	if len(fills) < 1 || fills[0] {
		p.ReadUser(m)
	}

	if len(fills) < 2 || fills[1] {
		p.ReadReSource(m)
	}

	if len(fills) < 3 || fills[2] {
		p.ReadCategory(m)
	}

	if len(fills) < 4 || fills[3] {
		p.ReadTag(m)
	}
	return nil
}

func (p MatterManager) FillMattersInfo(arr []*models.Matter, fills ...bool) error {
	for _, item := range arr {
		p.FillMatterInfo(item, fills...)
	}
	return nil
}

func (p MatterManager) GetAllMatters() ([]*models.Matter, error) {
	var arr []*models.Matter
	_, err := models.Orm.QueryTable("Matter").All(&arr)
	if err != nil {
		log.Log.Error("读取所有素材出错，%s", err)
		return nil, err
	}
	return arr, nil
}

func (p MatterManager) GetMattersByCat(catId int) ([]*models.Matter, error) {
	var arr []*models.Matter
	sql := fmt.Sprintf(`SELECT * FROM matter a where a.uuid in (select rel_id from categorys_map b where b.category_id='%d' and (flag='%d' or flag='%d'));`,
		catId, conf.F_Matter_PIC, conf.F_Matter_PSD)
	if _, err := models.Orm.Raw(sql).QueryRows(&arr); err != nil {
		log.Log.Error("读取分类<%d>关联素材，读取失败，%s", catId, err)
		return nil, err
	}

	return arr, nil
}

func (p MatterManager) GetMattersByTag(tagId int) ([]*models.Matter, error) {
	var arr []*models.Matter
	sql := fmt.Sprintf(`SELECT * FROM matter a where a.uuid in (select rel_id from tags_map b where b.tag_id='%d' and (flag='%d' or flag='%d'));`,
		tagId, conf.F_Matter_PIC, conf.F_Matter_PSD)
	if _, err := models.Orm.Raw(sql).QueryRows(&arr); err != nil {
		log.Log.Error("读取标签<%d>关联素材，读取失败，%s", tagId, err)
		return nil, err
	}
	return arr, nil
}

func (p MatterManager) GetCount(flag int) (int64, error) {
	var count int64
	var err error
	if flag <= 0 {
		count, err = models.Orm.QueryTable("Matter").Count()
	} else {
		count, err = models.Orm.QueryTable("Matter").Filter("Flag", flag).Count()
	}

	if err != nil {
		log.Log.Error("读取素材<%d>总个数，读取失败，%s", flag, err)
		return 0, err
	}
	return count, nil
}
